介紹
Typescript 具有強行別的功能,強型別的好處就是可以有推導,智能提示,重構時候也會有參考可以看哪些沒有改到是一種開發階段就會把一些錯誤處理掉,不會帶到編譯時候再來處理會節省很多Debug的時間,另外Typescript也把 babel next的部分都整合進來,可以直接用最新的功能。
TypeScript的基礎設定
安裝 typescript
npm i typescript
跟目錄下設定 tsconfig.ts 使用方法與基本設定可以參考
https://ithelp.ithome.com.tw/articles/10191127
Operation result
ApolloData 有一個 Typescript 直接 Query 回傳結果的範例 ,直接看一下程式碼
import React from "react";
import gql from "graphql-tag";
import { graphql } from "react-apollo";
const HERO_QUERY = gql`
query GetCharacter($episode: Episode!) {
hero(episode: $episode) {
name
id
friends {
name
id
appearsIn
}
}
}
`;
type Hero = {
name: string;
id: string;
appearsIn: string[];
friends: Hero[];
};
type Response = {
hero: Hero;
};
const withCharacter = graphql<Response>(HERO_QUERY, {
options: () => ({
variables: { episode: "JEDI" }
})
});
export default withCharacter(({ data: { loading, hero, error } }) => {
if (loading) return <div>Loading</div>;
if (error) return <h1>ERROR</h1>;
return ...// actual component with data;
});
可以看到 < Response > 就是graphql的型別
const withCharacter = graphql<Response>(HERO_QUERY, {
options: () => ({
variables: { episode: "JEDI" }
})
});
type Response 裡面 hero type 是 Hero
Hero 裡面的 appearsIn 是陣列裡面是 string 形態而 friends 的形態也是Type Hero
type Hero = {
name: string;
id: string;
appearsIn: string[];
friends: Hero[];
};
type Response = {
hero: Hero;
};
Options
如果要給查詢一個條件式的時候,以下範例定義了 < Response, InputProps > 比上方直接回傳結果多一個InputProps
import React from "react";
import gql from "graphql-tag";
import { graphql } from "react-apollo";
const HERO_QUERY = gql`
query GetCharacter($episode: Episode!) {
hero(episode: $episode) {
name
id
friends {
name
id
appearsIn
}
}
}
`;
type Hero = {
name: string;
id: string;
appearsIn: string[];
friends: Hero[];
};
type Response = {
hero: Hero;
};
type InputProps = {
episode: string
};
const withCharacter = graphql<Response, InputProps>(HERO_QUERY, {
options: ({ episode }) => ({
variables: { episode }
}),
});
export default withCharacter(({ data: { loading, hero, error } }) => {
if (loading) return <div>Loading</div>;
if (error) return <h1>ERROR</h1>;
return ...// actual component with data;
});
以上的 InputProps 定義為 episode: string 這邊是因為內部的 options會用到 props裡面有episode的型別參數
type InputProps = {
episode: string
};
Props
因為ApolloData 是使用 High Order Component (Hoc)的方法讓props多一些功能,
import React from "react";
import gql from "graphql-tag";
import { graphql, NamedProps, QueryProps} from "react-apollo";
const HERO_QUERY = gql`
query GetCharacter($episode: Episode!) {
hero(episode: $episode) {
name
id
friends {
name
id
appearsIn
}
}
}
`;
type Hero = {
name: string;
id: string;
appearsIn: string[];
friends: Hero[];
};
type Response = {
hero: Hero;
};
type WrappedProps = Response & QueryProps;
type InputProps = {
episode: string
};
const withCharacter = graphql<Response, InputProps, WrappedProps>(HERO_QUERY, {
options: ({ episode }) => ({
variables: { episode }
}),
props: ({ data }) => ({ ...data })
});
export default withCharacter(({ loading, hero, error }) => {
if (loading) return <div>Loading</div>;
if (error) return <h1>ERROR</h1>;
return ...// actual component with data;
});
以上可以看到 props: ({ data }) => ({ ...data }) 這一段 這裡面的是屬於
graphql< Response, InputProps, WrappedProps > 第三個WrappedProps的型別,然後這個地方使用了組合的type方法 因為 ApolloData本身的Hoc就有添加一些好用的的props,所以這邊
import { graphql, NamedProps, QueryProps} from "react-apollo";
把原本回回傳的 Response 加上 QueryProps 定義成 props會回傳的形態
type WrappedProps = Response & QueryProps;
Classes vs Functions
除了定義玩 graphql Hoc的部分之外 被綁定的React Component 也需要做點設定 ,使用 react-apollo 的ChildProps 再給他型別 InputProps, Response
import { ChildProps } from "react-apollo";
class Character extends React.Component< ChildProps<InputProps, Response>, {} >
import { ChildProps } from "react-apollo";
const withCharacter = graphql<Response, InputProps>(HERO_QUERY, {
options: ({ episode }) => ({
variables: { episode }
})
});
class Character extends React.Component<ChildProps<InputProps, Response>, {}> {
render(){
const { loading, hero, error } = this.props.data;
if (loading) return <div>Loading</div>;
if (error) return <h1>ERROR</h1>;
return ...// actual component with data;
}
}
export default withCharacter(Character);
總結
Typesciprt 是一個很棒的語言,在開發上速度會快很多減少Debug的時間,雖然型別設定上比較繁雜,但是一但開始用後,就回不去了啊。
ApolloData 官方文件參考
https://www.apollographql.com/docs/react/features/static-typing.html
TypeScript 官方文件參考
https://www.typescriptlang.org/